package com.hongye.proprietary.service.impl;

import com.alibaba.fastjson.JSON;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hongye.common.constant.ExamineStatusConstant;
import com.hongye.common.constant.OrderStatusConstant;
import com.hongye.common.utils.PageUtils;
import com.hongye.common.utils.Query;
import com.hongye.common.utils.R;
import com.hongye.proprietary.dao.HongyeOrderDao;
import com.hongye.proprietary.dao.PayUserDao;
import com.hongye.proprietary.entity.HongyeOrderEntity;
import com.hongye.proprietary.entity.PayUserEntity;
import com.hongye.proprietary.entity.UserHomeEntity;
import com.hongye.proprietary.fegin.HouseFegin;
import com.hongye.proprietary.fegin.PayFeignService;
import com.hongye.proprietary.service.HongyeOrderService;
import com.hongye.proprietary.vo.CoverImgVo;
import com.hongye.proprietary.vo.ExamineHomeVo;
import com.hongye.proprietary.vo.HouseImgVo;
import com.hongye.proprietary.vo.IndoorImgVo;
import com.hongye.proprietary.vo.OutdoorImgVo;
import com.hongye.proprietary.vo.PayAsyncVo;
import com.hongye.proprietary.vo.PayVo;
import com.hongye.proprietary.vo.RequirementVo;
import com.hongye.proprietary.vo.SaleHomeVo;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpSession;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Service("orderService")
public class HongyeOrderServiceImpl extends ServiceImpl<HongyeOrderDao, HongyeOrderEntity> implements HongyeOrderService {
    ThreadLocal<UserHomeEntity> userHomeEntityThreadLocal = new ThreadLocal<>();
    @Autowired
    private HttpSession session;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private HouseFegin houseFegin;
    @Autowired
    @SuppressWarnings("all")
    private PayUserDao payUserDao;
    @Autowired
    private PayFeignService payFeignService;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        UserHomeEntity loginUser = (UserHomeEntity) session.getAttribute("loginUser");
        QueryWrapper<HongyeOrderEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", 1);
        IPage<HongyeOrderEntity> page = this.page(
                new Query<HongyeOrderEntity>().getPage(params),
                wrapper
        );

        return new PageUtils(page);
    }

    @Override
    public R confirmOrder() {
        //获取当前登陆人信息
        UserHomeEntity loginUser = (UserHomeEntity) session.getAttribute("userlogin");
        userHomeEntityThreadLocal.set(loginUser);
        //令牌防重--》生成令牌
        String token = UUID.randomUUID().toString();
        redisTemplate.opsForValue().set("hongye" + loginUser.getUserId(), token);
        //防止ThreadLocal内存泄露
        userHomeEntityThreadLocal.remove();
        return R.ok().put("user", loginUser).put("token", token);
    }

    @GlobalTransactional
    @Override
    public R submitOrder(RequirementVo requirementVo) {
        String token = requirementVo.getToken();
        Integer userid = requirementVo.getRequirementUserid();
        String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
        Long result = redisTemplate.execute(new DefaultRedisScript<>(script, Long.class), Arrays.asList("hongye" + userid), token);
        if (result == 0L) {
            //验证失败
            return R.error(777,"该订单已提交过,请勿重复提交");
        } else {
            //验证成功  添加需求表
            requirementVo.setRequirementStatus(0);//默认未通过
            requirementVo.setRequirementType(1);//1求租2求购
            R save = houseFegin.saveRequirement(requirementVo);
            Object data = save.get("data");
            RequirementVo vo = JSON.parseObject(data + "", RequirementVo.class);
            //下订单
            HongyeOrderEntity orderEntity = new HongyeOrderEntity();
            orderEntity.setOrderCreatedate(new Date());
            orderEntity.setOrderNumber(IdWorker.getTimeId());
            orderEntity.setOrderPrice(10);
            orderEntity.setUserId(requirementVo.getRequirementUserid());
            orderEntity.setOriderType(requirementVo.getRequirementType());
            orderEntity.setOrderStatus(OrderStatusConstant.ORDER_CREATE);
            orderEntity.setRequirementId(vo.getRequirementId());
            orderEntity.setOrderClosetime(new Date(orderEntity.getOrderCreatedate().getTime() + (1000 * 60 * 30)));
            int i = baseMapper.insert(orderEntity);
            String pay = "";
            if (i > 0) {
                //将订单信息放入延时队列
                rabbitTemplate.convertAndSend("order-event-exchange", "order.create.order", orderEntity,new CorrelationData(UUID.randomUUID().toString()));
                //支付
                PayVo payVo = new PayVo();
                payVo.setOut_trade_no(orderEntity.getOrderNumber());
                payVo.setSubject(requirementVo.getRequirementContext());
                payVo.setBody(requirementVo.getRequirementDescription());
                payVo.setTotal_amount(orderEntity.getOrderPrice() + "");
                pay = payFeignService.pay(payVo);
            }
            //添加审核表
            ExamineHomeVo examineHomeVo = new ExamineHomeVo();
            examineHomeVo.setExamineStatus(ExamineStatusConstant.EXAMINE_CREATE);
            examineHomeVo.setUserId(requirementVo.getRequirementUserid());
            examineHomeVo.setRequirementId(vo.getRequirementId());
            examineHomeVo.setPublishType(requirementVo.getRequirementType());
            examineHomeVo.setOrderId(orderEntity.getOrderId());
            houseFegin.saveExamine(examineHomeVo);
            return R.ok("下订单成功").put("html", pay);
        }
    }

    @GlobalTransactional
    @Override
    public R submitOwnerOrder(SaleHomeVo saleHomeVo) {
        String token = saleHomeVo.getToken();
        Integer userId = saleHomeVo.getUserId();
        String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
        Long result = redisTemplate.execute(new DefaultRedisScript<>(script, Long.class), Arrays.asList("hongye" + userId), token);
        if (result == 0L) {
            //验证失败
            return R.error(777,"该订单已提交过,请勿重复提交");
        } else {
            //添加租房/售房表
            R r = houseFegin.save(saleHomeVo);
            Object data = r.get("data");
            SaleHomeVo vo = JSON.parseObject(data + "", SaleHomeVo.class);
            //添加封面图
            if (!StringUtils.isEmpty(saleHomeVo.getCoverImg())) {
                CoverImgVo coverImgVo = new CoverImgVo();
                coverImgVo.setCoverImg(saleHomeVo.getCoverImg());
                coverImgVo.setHouseId(vo.getHouseId());
                houseFegin.saveCoverImg(coverImgVo);
            }
            //添加户型图
            if (!StringUtils.isEmpty(saleHomeVo.getHouseImg())) {
                HouseImgVo houseImgVo = new HouseImgVo();
                houseImgVo.setHomeImg(saleHomeVo.getHouseImg());
                houseImgVo.setHouseId(vo.getHouseId());
                houseFegin.saveHouseImg(houseImgVo);
            }
            //添加室内图
            if (saleHomeVo.getIndoorImgs() != null && saleHomeVo.getIndoorImgs().size() > 0) {
                List<String> indoorImgs = saleHomeVo.getIndoorImgs();
                for (String indoorImg : indoorImgs) {
                    IndoorImgVo indoorImgVo = new IndoorImgVo();
                    indoorImgVo.setIndoorImg(indoorImg);
                    indoorImgVo.setHouseId(vo.getHouseId());
                    houseFegin.saveIndoorImg(indoorImgVo);
                }
            }
            //添加室外图
            if (saleHomeVo.getOutdoorImgs() != null && saleHomeVo.getOutdoorImgs().size() > 0) {
                List<String> outdoorImgs = saleHomeVo.getOutdoorImgs();
                for (String outdoorImg : outdoorImgs) {
                    OutdoorImgVo outdoorImgVo = new OutdoorImgVo();
                    outdoorImgVo.setOutdoorImg(outdoorImg);
                    outdoorImgVo.setHouseId(vo.getHouseId());
                    houseFegin.saveOutdoorImg(outdoorImgVo);
                }
            }
            //添加订单表
            HongyeOrderEntity orderEntity = new HongyeOrderEntity();
            orderEntity.setOrderCreatedate(new Date());
            orderEntity.setOrderNumber(IdWorker.getTimeId());
            orderEntity.setOrderPrice(10);
            orderEntity.setUserId(saleHomeVo.getUserId());
            orderEntity.setOriderType(saleHomeVo.getHouseType());
            orderEntity.setOrderStatus(OrderStatusConstant.ORDER_CREATE);
            orderEntity.setHouseId(vo.getHouseId());
            orderEntity.setOrderClosetime(new Date(orderEntity.getOrderCreatedate().getTime() + (1000 * 60 * 30)));
            int i = baseMapper.insert(orderEntity);
            String pay = "";
            if (i > 0) {
                //将订单信息放入延时队列
                rabbitTemplate.convertAndSend("order-event-exchange", "order.create.order", orderEntity,new CorrelationData(UUID.randomUUID().toString()));
                //支付
                PayVo payVo = new PayVo();
                payVo.setOut_trade_no(orderEntity.getOrderNumber());
                payVo.setSubject(saleHomeVo.getHouseAddress());
                payVo.setBody(saleHomeVo.getHouseDescription());
                payVo.setTotal_amount(orderEntity.getOrderPrice() + "");
                pay = payFeignService.pay(payVo);
            }
            //添加审核表
            ExamineHomeVo examineHomeVo = new ExamineHomeVo();
            examineHomeVo.setExamineStatus(ExamineStatusConstant.EXAMINE_CREATE);
            examineHomeVo.setUserId(saleHomeVo.getUserId());
            examineHomeVo.setPublishType(vo.getHouseId());
            examineHomeVo.setPublishType(saleHomeVo.getHouseType());
            examineHomeVo.setOrderId(orderEntity.getOrderId());
            houseFegin.saveExamine(examineHomeVo);
            return R.ok("下业主订单成功").put("html",pay);
        }

    }

    /*
     * 收到支付表回调信息
     * */
    @Override
    public String payNotify(PayAsyncVo payAsyncVo){
        //修改订单状态
        String out_trade_no = payAsyncVo.getOut_trade_no();
        HongyeOrderEntity orderEntity = baseMapper.selectOne(new QueryWrapper<HongyeOrderEntity>().eq("order_number", out_trade_no));
        orderEntity.setOrderStatus(OrderStatusConstant.ORDER_PAYED);
        baseMapper.updateById(orderEntity);
        //添加支付表
        PayUserEntity payUserEntity = new PayUserEntity();
        payUserEntity.setOrderNumber(out_trade_no);
        payUserEntity.setPayCreatetime(new Date());
        Date parse = null;
        try {
            parse = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(payAsyncVo.getGmt_payment());
        } catch (ParseException e) {
            e.printStackTrace();
        }
        payUserEntity.setPayPaytime(parse);
        payUserEntity.setPayThirdId(payAsyncVo.getTrade_no());
        payUserEntity.setPayStatus(1);
        payUserEntity.setPayThirdMessage(payAsyncVo.getSubject());
        int insert = payUserDao.insert(payUserEntity);
        return insert > 0 ? "success" : "fail";
    }

    @Override
    public void closeOrder(HongyeOrderEntity orderEntity) {
        //查询当前订单是否创建成功
        HongyeOrderEntity entity = baseMapper.selectById(orderEntity.getOrderId());
        if (entity.getOrderStatus().equals(OrderStatusConstant.ORDER_CREATE)) {
            //修改订单状态为已关闭
            HongyeOrderEntity hongyeOrderEntity = new HongyeOrderEntity();
            hongyeOrderEntity.setOrderId(orderEntity.getOrderId());
            hongyeOrderEntity.setOrderStatus(OrderStatusConstant.ORDER_CLOSE);
            baseMapper.updateById(hongyeOrderEntity);
            //修改审核表该订单记录为已关闭
            houseFegin.closeExamine(hongyeOrderEntity);
        }
    }

    @Override
    public void modifyOrderStatus(HongyeOrderEntity orderEntity) {
        orderEntity.setOrderStatus(OrderStatusConstant.ORDER_PAYED);
        baseMapper.updateById(orderEntity);
    }

    /*
    * 订单补偿
    * 主动调用支付宝查询交易状态方法，成功的交易修改订单状态
    * */
    public void compensateForOrder(){
        List<HongyeOrderEntity> entities = baseMapper.selectList(null);
        entities.forEach(hongyeOrderEntity -> {
            AlipayTradeQueryResponse response = payFeignService.transactionQuery(hongyeOrderEntity.getOrderNumber());
            if (response.isSuccess()){
                hongyeOrderEntity.setOrderStatus(OrderStatusConstant.ORDER_PAYED);
                baseMapper.updateById(hongyeOrderEntity);
            }
        });
    }

}